#-*- coding:utf-8 -*-
import numpy as np
import json

# Python2 JSON.load成Unicode的坑
# https://segmentfault.com/a/1190000002779638
def byteify(input, encoding='gbk'):
    if isinstance(input, dict):
        return {byteify(key):byteify(value) for key,value in input.iteritems()}
    elif isinstance(input, list):
        return [byteify(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode(encoding)
    else:
        return input

# 读取json格式的配置文件
def read_json_file(filename):
    # 读取json配置文件 
    f = open(filename, 'r')
    root = json.load(f)
    f.close()
    # 将unicode字符串变成str
    return byteify(root)

def read_topo_file(topo_file):
    A = np.loadtxt(topo_file)
    m, n = A.shape
    if n < 3:
        return []
    # 记录所有分支的数据
    edges = []
    for i in range(m):
        # 一条分支数据
        d = {
            'id':str(int(A[i, 0])),
            's':str(int(A[i, 1])),
            't':str(int(A[i, 2])),
            'r': 0.0
        }
        if n > 3:
            d['r'] = float(A[i, 3]) # 新增风阻数据
            # 排除风阻为0的情况
            if abs(1000*d['r']) < 1e-3:
                continue
        if n > 4:
            d['q'] = float(A[i, 4]) # 新增风量数据
        edges.append(d)
    return edges

def read_weight_file(weights, filename):
    all_weights = []
    f = open(filename)
    for line in f:
        datas = line.strip().split()
        if len(weights) != len(datas):
            continue
        weight_datas = {}
        for i in range(len(weights)):
            data_name = weights[i]['name']
            data_type = weights[i]['type']
            if data_type == 'int':
                weight_datas[data_name] = int(datas[i])
            elif data_type == 'float':
                weight_datas[data_name] = float(datas[i])
        all_weights.append(weight_datas)
    f.close()
    return all_weights

def read_graph_datas(json_file, encoding='gbk'):
    # 读取json数据文件
    graph_datas = read_json_file(json_file)
    # 将unicode字符串变成str
    graph_datas = byteify(graph_datas, encoding)
    # 默认不读取风量数据
    if 'hasQ' not in graph_datas:
        graph_datas['hasQ'] = False
    # 如果用户指定了拓扑数据文件
    if 'topo_file' in graph_datas:
        # 初始化分支数据
        if 'edges' not in graph_datas:
            graph_datas['edges'] = []
        # 读取拓扑数据
        graph_datas['edges'].extend(read_topo_file(graph_datas['topo_file']))

    # 如果用户指定了分支权重数据文件
    if 'edge_weights_file' in graph_datas:
        edge = graph_datas['edge_weights_file']
        if 'weights' in edge and 'file' in edge:
            if 'edge_weights' not in graph_datas:
                graph_datas['edge_weights'] = []
            graph_datas['edge_weights'].extend(read_weight_file(edge['weights'], edge['file']))
    
    # 如果用户指定了节点权重数据文件
    if 'node_weights_file' in graph_datas:
        node = graph_datas['node_weights_file']
        if 'weights' in node and 'file' in node:
            if 'node_weights' not in graph_datas:
                graph_datas['node_weights'] = []
            graph_datas['node_weights'].extend(read_weight_file(node['weights'], node['file']))            
    return graph_datas

#构造网络数据1
def build_graph_data1():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.375,"s":1,"t":2},
            {"id":2,"r":1.50,"s":2,"t":3},
            {"id":3,"r":2.0,"s":2,"t":4},
            {"id":4,"r":4.6875,"s":3,"t":5},
            {"id":5,"r":12.5,"s":3,"t":4},
            {"id":6,"r":1.7361,"s":4,"t":5},
            {"id":7,"r":0.5,"s":5,"t":6}
        ],
        "fans":[
            {"a0":1046.3,"a1":5.0,"a2":-0.85,"eID":7}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas
#构造网络数据2
def build_graph_data2():
    graph_datas = {
        "edges": [
            {"id":0,"r":0.08,"s":0,"t":1},
            {"id":1,"r":0.14,"s":0,"t":4},
            {"id":2,"r":0.20,"s":1,"t":2},
            {"id":3,"r":0.65,"s":2,"t":3},
            {"id":4,"r":0.20,"s":4,"t":3},
            {"id":5,"r":1.02,"s":1,"t":5},
            {"id":6,"r":1.0,"s":2,"t":6},
            {"id":7,"r":1.0,"s":3,"t":8},
            {"id":8,"r":1.20,"s":4,"t":9},
            {"id":9,"r":0.30,"s":5,"t":6},
            {"id":10,"r":0.32,"s":6,"t":7},
            {"id":11,"r":0.33,"s":8,"t":7},
            {"id":12,"r":0.30,"s":8,"t":9},
            {"id":13,"r":0.80,"s":5,"t":10},
            {"id":14,"r":0.12,"s":7,"t":10},
            {"id":15,"r":0.34,"s":9,"t":10},
            {"id":16,"r":0.13,"s":10,"t":11}
        ],
        "fans": [
            {"a0":12955.830,"a1":407.387750,"a2":-3.87750,"eID":16}
        ],
        "gates": [
            #{"area":5.179553058241189e-270,"eID":4,"r":50.0}
        ],
        "qFixs": [
            {"eID":10,"fq":33},
            {"eID":4,"fq":24}
        ]
    }
    return graph_datas

#构造网络数据3
def build_graph_data3():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.375,"s":1,"t":2},
            {"id":2,"r":1.50, "s":2,"t":3},
            {"id":3,"r":2.0,  "s":2,"t":4},
            {"id":4,"r":4,    "s":3,"t":7},
            {"id":5,"r":5.6,  "s":3,"t":5},
            {"id":6,"r":4.5,  "s":4,"t":5},
            {"id":7,"r":6.4,  "s":4,"t":6},
            {"id":8,"r":5,    "s":5,"t":6},
            {"id":9,"r":1.8,  "s":6,"t":7},
            {"id":10,"r":0.5, "s":7,"t":8}
        ],
        "fans":[
            {"a0":1046.3,"a1":5.0,"a2":-0.85,"eID":10}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas

def build_graph_data4():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.375,"s":1,"t":2},
            {"id":2,"r":1.50,"s":2,"t":3},
            {"id":3,"r":2.0,"s":2,"t":4},
            {"id":4,"r":4.6875,"s":3,"t":5},
            {"id":5,"r":12.5,"s":3,"t":4},
            {"id":6,"r":1.7361,"s":4,"t":5},
            {"id":7,"r":0.5,"s":5,"t":6}
        ],
        "fans":[
            {"a0":1046.3,"a1":5.0,"a2":-0.85,"eID":7}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas

def build_graph_data5():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.375,"s":1,"t":2},
            {"id":2,"r":1.50,"s":2,"t":3},
            {"id":3,"r":2.0,"s":2,"t":4},
            {"id":4,"r":4.6875,"s":3,"t":5},
            {"id":5,"r":12.5,"s":3,"t":4},
            {"id":6,"r":1.7361,"s":4,"t":5},
            {"id":7,"r":0.5,"s":5,"t":6}
        ],
        "fans":[
            {"a0":1046.3,"a1":5.0,"a2":-0.85,"eID":7}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas

def build_graph_data6():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.054,"s":1,"t":2},
            {"id":2,"r":0.1457,"s":2,"t":3},
            {"id":3,"r":0.2396,"s":2,"t":4},
            {"id":4,"r":0.5337,"s":3,"t":5},
            {"id":5,"r":6.6536,"s":3,"t":4},
            {"id":6,"r":0.3957,"s":4,"t":5},
            {"id":7,"r":0.0820,"s":5,"t":6}
        ],
        "fans":[
            {"a0":1035.92,"a1":51.73,"a2":-0.43,"eID":7}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas

def build_graph_data7():
    graph_datas = {
        "edges":[
            {"id":1,"r":0.0540, "s":1,"t":2},
            {"id":2,"r":0.1457, "s":2,"t":3},
            {"id":3,"r":0.1341, "s":2,"t":4},
            {"id":4,"r":0.5337, "s":3,"t":7},
            {"id":5,"r":6.1286, "s":3,"t":5},
            {"id":6,"r":1.3827, "s":4,"t":5},
            {"id":7,"r":1.6637, "s":5,"t":6},
            {"id":8,"r":0.1849, "s":4,"t":6},
            {"id":9,"r":0.3957, "s":6,"t":7},
            {"id":10,"r":0.0820, "s":7,"t":8}
        ],
        "fans":[
            {"a0":1035.92,"a1":51.73,"a2":-0.43,"eID":10}
        ],
        "maxCount":1000,
        "q_precise": 0.0001,
        "h_precise": 1.0,
    }
    return graph_datas    